/*
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV50_VIDEO_DECODER)

#include <ippi.h>
#include <ippvc.h>
#include "umc_dv50_decoder.h"
#include "umc_dv50_internal.h"

namespace UMC
{

const Ipp32u lMacroBlockWidth422 = 8 * 2;
const Ipp32u lMacroBlockHeight422 = 8;
const Ipp32u lSuperBlockWidth422 = (lMacroBlockWidth422 * 9);
const Ipp32u lSuperBlockHeight422 = (lMacroBlockHeight422 * 3);

void DV50VideoDecoder::InitializeStoreDV50Info(STORE_DV_SEGMENT_INFO &StoreInfo, Ipp32u i, Ipp32u k, Ipp32u nThreadNum)
{
    Ipp16u *lpsBlock = m_ppShortBlocks[nThreadNum];
    Ipp32u lRow, lCol, lBytesPerPixel = 0;
    Ipp32u NumDIFSeq = m_nMaxNumberOfDIFSequences / 2;

    StoreInfo.m_lPitch = m_nPitch;

    // get current column
    lCol = k / 3;

    // get current row
    if (lCol & 0x01)
        lRow = 2 - (k % 3);
    else
        lRow = (k % 3);

    // we use following formula:
    // dest buffer +
    // needed super block row offset +
    // needed super block column offset +
    // needed macro block row offset +
    // needed macro block column offset
    lBytesPerPixel = 2;
    StoreInfo.m_lpsSource[0] = lpsBlock + (6 * 64 * 0);
    StoreInfo.m_lpbDestination[0] = m_lpDestination +
                                    ((i / NumDIFSeq) * m_nPitch * lSuperBlockHeight422 +
                                    ((i + 2) % NumDIFSeq) * m_nPitch * lSuperBlockHeight422 * 2 +
                                    m_nPitch * lMacroBlockHeight422 * lRow +
                                    ((2) * lSuperBlockWidth422 +
                                    lMacroBlockWidth422 * lCol) * lBytesPerPixel) / m_lSizeSubSampled;

    StoreInfo.m_lpsSource[1] = lpsBlock + (6 * 64 * 1);
    StoreInfo.m_lpbDestination[1] = m_lpDestination +
                                    ((i / NumDIFSeq) * m_nPitch * lSuperBlockHeight422 +
                                    ((i + 6) % NumDIFSeq) * m_nPitch * lSuperBlockHeight422 * 2 +
                                    m_nPitch * lMacroBlockHeight422 * lRow +
                                    ((1) * lSuperBlockWidth422 +
                                    lMacroBlockWidth422 * lCol) * lBytesPerPixel) / m_lSizeSubSampled;

    StoreInfo.m_lpsSource[2] = lpsBlock + (6 * 64 * 2);
    StoreInfo.m_lpbDestination[2] = m_lpDestination +
                                    ((i / NumDIFSeq) * m_nPitch * lSuperBlockHeight422 +
                                    ((i + 8) % NumDIFSeq) * m_nPitch * lSuperBlockHeight422 * 2 +
                                    m_nPitch * lMacroBlockHeight422 * lRow +
                                    ((3) * lSuperBlockWidth422 +
                                    lMacroBlockWidth422 * lCol) * lBytesPerPixel) / m_lSizeSubSampled;

    StoreInfo.m_lpsSource[3] = lpsBlock + (6 * 64 * 3);
    StoreInfo.m_lpbDestination[3] = m_lpDestination +
                                    ((i / NumDIFSeq) * m_nPitch * lSuperBlockHeight422 +
                                    ((i + 0) % NumDIFSeq) * m_nPitch * lSuperBlockHeight422 * 2 +
                                    m_nPitch * lMacroBlockHeight422 * lRow +
                                    ((0) * lSuperBlockWidth422 +
                                    lMacroBlockWidth422 * lCol) * lBytesPerPixel) / m_lSizeSubSampled;

    StoreInfo.m_lpsSource[4] = lpsBlock + (6 * 64 * 4);
    StoreInfo.m_lpbDestination[4] = m_lpDestination +
                                    ((i / NumDIFSeq) * m_nPitch * lSuperBlockHeight422 +
                                    ((i + 4) % NumDIFSeq) * m_nPitch * lSuperBlockHeight422 * 2 +
                                    m_nPitch * lMacroBlockHeight422 * lRow +
                                    ((4) * lSuperBlockWidth422 +
                                    lMacroBlockWidth422 * lCol) * lBytesPerPixel) / m_lSizeSubSampled;

} // void DV50VideoDecoder::InitializeStoreDV50Info(STORE_DV_SEGMENT_INFO &StoreInfo, Ipp32u i, Ipp32u k, Ipp32u nThreadNum)

void DV50VideoDecoder::StoreDV50Segment(Ipp32u i, Ipp32u k, Ipp32u nThreadNum)
{
    STORE_DV_SEGMENT_INFO RealStoreInfo;

    // reset pointers
    InitializeStoreDV50Info(RealStoreInfo, i, k, nThreadNum);

    ippiYCrCb422ToYCbCr422_5MBDV_16s8u_P3C2R((const Ipp16s **) RealStoreInfo.m_lpsSource,
                                             RealStoreInfo.m_lpbDestination,
                                             (Ipp32s) RealStoreInfo.m_lPitch);

} // void DV50VideoDecoder::StoreDVSegment(Ipp32u i, Ipp32u k, Ipp32u nThreadNum)

} // end namespace UMC

#endif //(UMC_ENABLE_DV50_VIDEO_DECODER)
